// 导入RouterLink组件和RouterView组件
import RouterLink from './RouterLink.vue'
import RouterView from './RouterView.vue'
// 导入Vue的ref和inject函数用于响应式和依赖注入
import { ref, inject } from 'vue'

/**
 * 创建一个路由器实例。
 * @param {Object} options - 路由器配置选项，包括历史模式和路由配置。
 * @returns {Router} - 返回一个Router实例。
 */
export const createRouter = (options) => {
    return new Router(options)
}

/**
 * 创建一个基于Hashchange事件的浏览器历史管理对象。
 * @returns {Object} - 返回一个包含url和bindEvents方法的对象。
 */
export const createWebHashHistory = () => {
    /**
     * 绑定hashchange事件监听函数。
     * @param {Function} fn - 当hash改变时调用的回调函数。
     */
    function bindEvents(fn) {
        window.addEventListener('hashchange', fn)
    }
    // 初始化url为当前的hash值，如果没有则默认为'/'
    // history 对象
    return {
        url: window.location.hash.slice(1) || '/',
        bindEvents
    }
}

// 定义一个常量作为路由器的提供键
// 标记一下   router 要向全世界暴露
const ROUTER_KEY = '__router__'

/**
 * 获取当前应用的路由器实例。
 * @returns {Router} - 返回通过依赖注入获取的Router实例。
 */
export const userRouter = () => {
    return inject(ROUTER_KEY)
}

/**
 * 路由器类。
 */
class Router {
    /**
     * 创建一个路由器实例。
     * @param {Object} options - 路由器配置选项，包括历史模式和路由配置。
     */
    constructor(options) {
        // 初始化历史模式对象
        this.history = options.history
        // 初始化路由配置数组
        this.routes = options.routes
        // 初始化当前路由的响应式引用
        this.current = ref(this.history.url)
        // 绑定历史模式的事件监听，更新当前路由
        this.history.bindEvents(() => {
            this.current.value = window.location.hash.slice(1)
        })
    }

    /**
     * 将路由器安装到Vue应用中。
     * @param {Object} app - Vue应用实例。
     */
    // use 调用 插件install
    install(app) {
        // 为Vue应用提供路由器实例
        // 全局声明有一个router 全局使用的对象
        app.provide(ROUTER_KEY, this)
        // 注册RouterLink和RouterView组件
        console.log('准备与vue 对接', app)
        app.component('router-link', RouterLink)
        app.component('router-view', RouterView)
    }
}